package com.jdd.modules.parkcar.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jdd.common.api.vo.Result;
import com.jdd.common.client.ParkCloudHttpClient;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.*;
import com.jdd.modules.area.entity.ParkAreaInfo;
import com.jdd.modules.area.service.IParkAreaInfoService;
import com.jdd.modules.parkcar.entity.ParkCarMonthly;
import com.jdd.modules.parkcar.entity.ParkSpace;
import com.jdd.modules.parkcar.mapper.ParkSpaceMapper;
import com.jdd.modules.parkcar.service.IParkCarMonthlyService;
import com.jdd.modules.parkcar.service.IParkSpaceService;
import com.jdd.modules.parking.entity.ParkCarEnterLog;
import com.jdd.modules.parking.entity.ParkInfo;
import com.jdd.modules.parking.service.IParkInfoService;
import com.jdd.modules.parkmonthly.vo.AddMonthlySpace;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 车位管理
 * @Author: jdd
 * @Date: 2021-05-31
 * @Version: V1.0
 */
@Service
@Slf4j
public class ParkSpaceServiceImpl extends ServiceImpl<ParkSpaceMapper, ParkSpace> implements IParkSpaceService {


    @Resource
    private IParkInfoService parkInfoService;
    @Resource
    private IParkAreaInfoService parkAreaInfoService;
    @Resource
    private IParkCarMonthlyService parkCarMonthlyService;
    @Resource
    private ParkSpaceMapper parkSpaceMapper;
    @Resource
    private MonthlyUploadHttpUtils monthlyUploadHttpUtils;
    @Resource
    private ParkCloudHttpClient parkCloudHttpClient;

    /**
     * 月卡 新增车位
     *
     * @param parkSpace
     * @return
     */
    @Override
    public Result<?> addNew(ParkSpace parkSpace) {
        log.info("月卡新增，车位信息传入参数-------------------》:{}", parkSpace);
        Result<?> result = new Result<>();
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        parkSpace.setId(SnowFlakeUtil.getId());
        ParkInfo parkInfo = parkInfoService.getParkInfoByParkCode();
        parkSpace.setParkCode(parkInfo.getParkCode());
        parkSpace.setParkName(parkInfo.getParkName());
        parkSpace.setCreateUser(loginUser.getUsername());
        parkSpace.setCreateTime(new Date());
        List<String> parkNumberList = new ArrayList<>();
        Integer startNumber = parkSpace.getStartNumber();
        Integer placeNos = parkSpace.getPlaceNos();
        String areaCode = parkSpace.getAreaCode();
        for (int i = 0; i < placeNos; i++) {
            parkNumberList.add(getMonthlyCode(startNumber, i, areaCode));
        }
        LambdaQueryWrapper<ParkSpace> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ParkSpace::getParkNumber, parkNumberList);
        queryWrapper.in(ParkSpace::getAreaCode, parkSpace.getAreaCode());
        queryWrapper.in(ParkSpace::getAreaId, parkSpace.getAreaId());
        List<ParkSpace> list = this.list(queryWrapper);
        if (list.size() > 0) {
            return result.error500("改区间存在相同车位");
        }
        ParkAreaInfo parkAreaInfo = parkAreaInfoService.getById(parkSpace.getAreaId());
        parkSpace.setAreaName(parkAreaInfo.getAreaName());
        List<ParkSpace> spaceList = new ArrayList<>();
        parkSpace.setParkStatus("0");
        for (String parkNumber : parkNumberList) {
            ParkSpace space = parkSpace;
            space.setId(SnowFlakeUtil.getId());
            space.setParkNumber(parkNumber);
            space.setStatus("Y");
            spaceList.add(space);
            log.info("新增车位信息parkNumber-------------》:{}", space);
            this.save(space);
        }
        log.info("新增车位信息列表-------------》:{}", spaceList);
        return Result.ok("新增成功！");
    }

    /**
     * 月卡编号生成规则
     *
     * @return
     */
    public String getMonthlyCode(int startNumber,int placeNo,String areaCode) {
        int num = startNumber + placeNo;
        if (num < 10) {
            return areaCode+"00" +num;
        } else if (num >= 10 && num < 100) {
            return areaCode+"0" + num;
        } else if (num >= 100 && num < 1000) {
            return areaCode +num;
        }  else {
            return null;
        }
    }

    /**
     * 查询车场下，对应区域权限的车位
     *
     * @param permissionId 权限id
     * @return 车位号
     */
    @Override
    public List<ParkSpace> getFreeSpaces(String permissionId) {
        return parkSpaceMapper.getFreeSpaces(permissionId);
    }

    /**
     * 月卡 删除车位
     *
     * @param id
     * @return
     */
    @Override
    public Result<?> deleteNew(String id) {
        try {
            ParkSpace parkSpace = this.getById(id);
            LambdaQueryWrapper<ParkCarMonthly> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ParkCarMonthly::getParkNumber, parkSpace.getParkNumber());
            List<ParkCarMonthly> parkCarMonthlyList = parkCarMonthlyService.list(queryWrapper);
            if (CollectionUtils.isNotEmpty(parkCarMonthlyList)) {
                return Result.error("车位编号" + parkSpace.getParkNumber() + "存在绑定的月租信息，不允许删除！");
            }
            this.removeById(id);
        } catch (Exception e) {
            log.error("删除失败", e.getMessage());
            return Result.error("删除失败!");
        }
        return Result.ok("删除成功!");
    }

    /**
     * 更改车辆车位的状态
     *
     * @param parkCarEnterLog 区域id
     * @param parkStatus      车位状态：0，无车辆停靠；1，有车辆停靠
     * @return 更新成功还是失败
     * @author renshangyi
     * @date 2021-08-18
     */
    @Override
    public boolean updateParkStatus(ParkCarEnterLog parkCarEnterLog, String parkStatus) {
        if (parkCarEnterLog == null) {
            return false;
        }
        log.info("更新月租车位状态,区域id:{},车位号：{}", parkCarEnterLog.getAreaId(), parkCarEnterLog.getParkNumber());
        UpdateWrapper<ParkSpace> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("area_id", parkCarEnterLog.getAreaId())
                .eq("park_number", parkCarEnterLog.getParkNumber())
                .set("park_status", parkStatus);
        return this.update(updateWrapper);
    }

    /**
     * 清空表数据
     */
    @Override
    public void removeAllInfo() {
        parkSpaceMapper.removeAllInfo();
    }

    /**
     * 更改车辆车位的状态
     *
     * @param parkCarEnterLog 区域id
     * @param parkStatus      车位状态：0，无车辆停靠；1，有车辆停靠
     * @return 更新成功还是失败
     * @author renshangyi
     * @date 2021-08-18
     */
    @Override
    public boolean updateParkStatusV3(ParkCarEnterLog parkCarEnterLog, String parkStatus, String plateNo) {
        if (parkCarEnterLog == null) {
            return false;
        }
        log.info("更新月租车位状态,区域id:{},车位号：{}", parkCarEnterLog.getAreaId(), parkCarEnterLog.getParkNumber());
        UpdateWrapper<ParkSpace> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("area_id", parkCarEnterLog.getAreaId())
                .eq("park_number", parkCarEnterLog.getParkNumber())
                .set("park_status", parkStatus)
                .set("plate_no", plateNo);
        return this.update(updateWrapper);
    }

    /**
     * 更改车辆车位的状态
     *
     * @param parkCarEnterLog 区域id
     * @param parkStatus      车位状态：0，无车辆停靠；1，有车辆停靠
     * @return 更新成功还是失败
     * @author renshangyi
     * @date 2021-08-18
     */

    @Override
    public boolean updateParkStatusNullV3(ParkCarEnterLog parkCarEnterLog, String parkStatus) {
        if (parkCarEnterLog == null) {
            return false;
        }
        log.info("更新月租车位状态,区域id:{},车位号：{}", parkCarEnterLog.getAreaId(), parkCarEnterLog.getParkNumber());
        UpdateWrapper<ParkSpace> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("area_id", parkCarEnterLog.getAreaId())
                .eq("plate_no", parkCarEnterLog.getPlateNo())
                .set("park_status", parkStatus)
                .set("plate_no", null);
        return this.update(updateWrapper);
    }

    /**
     * 批量创建车位
     *
     * @param parkSpaces
     */
    @Transactional
    @Override
    public void addParkSpaces(List<ParkSpace> parkSpaces) {
        try {
            this.saveBatch(parkSpaces);
            String str = JSONObject.toJSONString(parkSpaces);
            AddMonthlySpace addMonthlySpace = new AddMonthlySpace();
            addMonthlySpace.setJudge(true);
            addMonthlySpace.setStr(str);
            monthlyUploadHttpUtils.postMonthlyUpload("", addMonthlySpace);

        } catch (Exception e) {
            log.error("处理场端同步车位信息出现异常,进行数据回滚!", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String str = JSONObject.toJSONString(parkSpaces);
            AddMonthlySpace addMonthlySpace = new AddMonthlySpace();
            addMonthlySpace.setJudge(false);
            addMonthlySpace.setStr(str);
            monthlyUploadHttpUtils.postMonthlyUpload("", addMonthlySpace);

        }
    }

    /**
     * @param parkSpace
     * @param page
     * @return
     * @Title: getParkSpacePageList
     * @Description:查询月租车位信息带分页
     * @author: zjf
     * @date 2022年1月19日
     * @version 1.0
     */

    @Override
    public IPage<ParkSpace> getParkSpacePageList(ParkSpace parkSpace, Page<ParkSpace> page) {
        return parkSpaceMapper.getParkSpacePageList(page, parkSpace);
    }

    /**
     * @param parkCode
     * @param plateNo
     * @param licenseStatusY
     * @return
     * @Title: getParkSpaceListCount
     * @Description:查询月租车是否有剩余车位
     * @author: zjf
     * @date 2022年1月25日
     * @version 1.0
     */

    @Override
    public boolean getParkSpaceListCount(String parkCode, String plateNo, String licenseStatusY, List<ParkCarMonthly> parkCarMonthlyList) {
        // 保存有效未占位车位
        String monthlyCardId = "";
        if (CollectionUtils.isNotEmpty(parkCarMonthlyList)) {
            ParkCarMonthly parkCarMonthly = parkCarMonthlyList.get(0);
            // 月租车未过期
            if (DateUtil.betweenDateTime(new Date(), parkCarMonthly.getStartTime(), parkCarMonthly.getEndTime())) {
                monthlyCardId = parkCarMonthly.getMonthlyCardId();
            }
        }
        if (StringUtils.isNotBlank(monthlyCardId)) {
            QueryWrapper<ParkSpace> queryWrapper = new QueryWrapper<ParkSpace>();
            queryWrapper.in("monthly_card_id", monthlyCardId);
            queryWrapper.eq("status", licenseStatusY);
            List<ParkSpace> parkSpaceList = parkSpaceMapper.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(parkSpaceList)) {
                return true;
            }
            for (ParkSpace parkSpace : parkSpaceList) {
                // 如果传入的车牌号和查询出的车牌号相同则有车位
                if (StringUtils.isNotBlank(plateNo) && plateNo.equals(parkSpace.getPlateNo())) {
                    return true;
                }
                // 获取空闲车位
                if (JddConstant.StringNumber.STRING_ZERO.equals(parkSpace.getParkStatus())) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 查询区域内未绑定月租套餐的车位信息
     *
     * @param areaId
     * @param status
     * @return
     */
    @Override
    public List<ParkSpace> getByAreaEffeParkNumber(String areaId, String status) {
        return parkSpaceMapper.getByAreaEffeParkNumberList(areaId, status);
    }

	@Override
	public void updateBatchParkSpaceById(List<ParkSpace> list) {
		parkSpaceMapper.updateBatchParkSpaceById(list);
	}

	@Override
	public List<ParkSpace> getByAreaParkSpace(String areaId, String status) {
		LambdaQueryWrapper<ParkSpace> wrapper = Wrappers.lambdaQuery();
		//wrapper.eq(ParkSpace::getAreaId, areaId);
		wrapper.eq(ParkSpace::getStatus, status);
		return parkSpaceMapper.selectList(wrapper);
	}
	@Override
    public boolean updateParkPlateNo(String parkNumber,String areaId,String plateNo){
        LambdaQueryWrapper<ParkSpace> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ParkSpace::getParkNumber,parkNumber);
        wrapper.eq(ParkSpace::getAreaId,areaId);
        ParkSpace parkSpace = new ParkSpace();
        parkSpace.setPlateNo(plateNo);
        return this.update(parkSpace,wrapper);
    }

    /**
     * 获取占据车位的车牌号
     * */
    @Override
    public List<ParkSpace> getParkCarNumber(String monthlyCardId,String areaId){
        return parkSpaceMapper.getParkCarNumber(monthlyCardId,areaId);
    }
    @Override
    public boolean updateSpaceCar(ParkSpace parkSpace ,String plateNo){
        parkSpace.setPlateNo(plateNo);
        return this.updateById(parkSpace);
    }
    @Override
    public Integer updateSpaceNoPlate(ParkSpace parkSpace){
        parkSpace.setPlateNo("");
        parkSpace.setParkStatus("0");
        return parkSpaceMapper.updateById(parkSpace);
    }
}
